package com.chuangsi.project.admin.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.chuangsi.common.constant.Constants;
import com.chuangsi.common.exception.ServiceException;
import com.chuangsi.common.utils.ConfigUtil;
import com.chuangsi.common.utils.LocalDateTimeUtils;
import com.chuangsi.framework.config.WxPayConfig;
import com.chuangsi.framework.redis.RedisCache;
import com.chuangsi.project.admin.dto.wechat.WxAccessTokenDto;
import com.chuangsi.project.admin.dto.wechat.WxOpenIdDto;
import com.chuangsi.project.admin.dto.wechat.WxTemplateDataDto;
import com.chuangsi.project.admin.service.WechatService;
import com.chuangsi.project.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class WechatServiceImpl implements WechatService {

	@Autowired
	private ConfigUtil configUtil;
	@Autowired
	private RedisCache redisCache;
	@Autowired
	private ISysUserService sysUserService;
	@Autowired
	private WxPayConfig wxPayConfig;

	public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	public final static String miniprogram_openid_url = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
	public final static String miniprogram_message_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";




	/**
	 * 获取接口访问凭证
	 *
	 * @return
	 */
	@Override
	public synchronized String getAccessToken() {
		if(redisCache.hasKey(Constants.GZH_ACCESSTOKEN)){
			return redisCache.getCacheObject(Constants.GZH_ACCESSTOKEN);
		}else {
			String accessToken = "";
			WxAccessTokenDto accessTokenDto = getGzhAccessToken();
			if(accessTokenDto!=null && StrUtil.isNotBlank(accessTokenDto.getAccess_token())){
				accessToken = accessTokenDto.getAccess_token();
			}else {
				//如果没有token,那么就去获取，循环5次
				for (int i = 0; i < 5; i++) {
					accessTokenDto = getGzhAccessToken();
					if(accessTokenDto!=null && StrUtil.isNotBlank(accessTokenDto.getAccess_token())){
						accessToken = accessTokenDto.getAccess_token();
						break;
					}
					ThreadUtil.sleep(1000);
				}
			}
			if(StrUtil.isNotBlank(accessToken)){
				redisCache.setCacheObject(Constants.GZH_ACCESSTOKEN,accessToken,7100, TimeUnit.SECONDS);
				return accessToken;
			}else {
				throw new ServiceException("微信获取ACCESSTOKEN失败");
			}
		}
	}


	public WxAccessTokenDto getGzhAccessToken(){
		try {
			String obj = HttpUtil.get(token_url.replace("APPID", wxPayConfig.getAppId()).replace("APPSECRET",  wxPayConfig.getAppSecret()));
			log.info("微信返回TOKEN:{}",obj);
			if(StrUtil.isNotBlank(obj)){
				return JSONUtil.toBean(obj, WxAccessTokenDto.class);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return null;
	}



	@Override
	public void sendModelMessage(String openId,String templateId,Map<String, WxTemplateDataDto> data,String jumpUrl)  {
		//获取accessToken
		String accessToken = getAccessToken();
		String url = miniprogram_message_url + accessToken;
		JSONObject params=new JSONObject();
		params.put("touser",openId);
		params.put("template_id",templateId);
		params.put("data",data);
		if(StrUtil.isNotBlank(jumpUrl)){
			params.put("url",jumpUrl);
		}
		try {
			String res=HttpUtil.post(url,params.toString());
			cn.hutool.json.JSONObject wechatres=JSONUtil.parseObj(res);
			if(!wechatres.get("errcode").toString().equals("0")){
				log.error("发送模板消息返回："+res);
			}
		}catch (Exception e){
			log.error(e.getMessage());
		}
	}

	@Override
	public String getOpenId(String code) {
		String url = String.format(miniprogram_openid_url, wxPayConfig.getAppId(), wxPayConfig.getAppSecret(), code);
		String msg = HttpUtil.post(url,"");
		WxOpenIdDto openIdDto = JSONUtil.toBean(msg, WxOpenIdDto.class);
		log.info("code内容：{}",code);
		log.info("获取到的openid结果：{}",msg);
		if(openIdDto.getErrcode() == null){
			sysUserService.insertCustomer(openIdDto.getOpenid());
			return openIdDto.getOpenid();
		}else {
			throw new ServiceException("获取openId失败");
		}
	}

}